<?php

class Helper_Head
{
	/**
	 * @var array
	 */
	protected $_vars = array();

	/**
	 * @var array
	 */
	protected $_options = array();

	/**
	 * constructor
	 */
	public function __construct()
	{
		$this -> _options = Agis::getTable('core@setting') -> getAll('site.head');
	}

	/**
	 * @param string $name
	 * @return array
	 */
	public function getVar($name)
	{
		$name = strtolower($name);
		return isset($this -> _vars[$name]) ? $this -> _vars[$name] : array();
	}

	/**
	 * @return array
	 */
	public function getOptions()
	{
		return $this -> _options;
	}

	/**
	 * @param array $options
	 * @return
	 */
	public function setOptions($options)
	{
		$this -> _options = $options;
		return $this;
	}

	/**
	 * @param string $name
	 * @param string $value
	 */
	public function setOption($name, $value)
	{
		$this -> _options[$name] = $value;
		return $this;
	}

	/**
	 * @param string $name
	 * @param string $value
	 * @return string
	 */
	public function getOption($name, $default = '')
	{
		return isset($this -> _options[$name]) ? $this -> _options[$name] : $default;
	}

	/**
	 * get html from current tile
	 * @return
	 */
	public function getHtmlFromTitle()
	{
		return sprintf('<title>%s</title>', implode($this -> getOption('title-separate', '-'), $this -> getVar('title')));
	}

	/**
	 * flatten meta to html
	 * @return string
	 */
	public function getHtmlFromMeta()
	{
		$xhtml = array();

		foreach ($this->getVar('Meta') as $meta)
		{
			$xhtml[] = '<meta ' . $this -> __flattenAttribs($meta) . '/>';
		}
		return implode(PHP_EOL, $xhtml);
	}

	/**
	 * flatten keyword to html
	 * @return string
	 */
	public function getHtmlFromKeyword()
	{
		return '<meta name="keyword" content="' . implode(', ', $this -> getVar('keyword')) . '"/>';
	}

	/**
	 * flatten description to html
	 * @return string
	 */
	public function getHtmlFromDescription()
	{
		return '<meta name="description" content="' . implode(', ', $this -> getVar('description')) . '"/>';
	}

	/**
	 * flatten link to html
	 * @return string
	 */
	public function getHtmlFromLink()
	{
		$xhtml = array();

		foreach ($this->getVar('Link') as $value)
		{
			$xhtml[] = '<link ' . $this -> __flattenAttribs($value) . '/>';
		}
		return implode(PHP_EOL, $xhtml);
	}

	/**
	 * flatten css link to html
	 * @return string
	 */
	public function getHtmlFromCssLink()
	{
		$xhtml = array();

		foreach ($this->getVar('CssLink') as $value)
		{
			$xhtml[] = '<link ' . $this -> __flattenAttribs($value) . '/>';
		}
		return implode(PHP_EOL, $xhtml);
	}

	/**
	 * flatten js link to html
	 * @return string
	 */
	public function getHtmlFromJsLink()
	{
		$xhtml = array();
		foreach ($this->getVar('JsLink') as $value)
		{
			$xhtml[] = '<script ' . $this -> __flattenAttribs($value) . '></script>';
		}
		return implode(PHP_EOL, $xhtml);
	}

	/**
	 * get base href tags
	 * @return string
	 */
	public function getHtmlFromBase()
	{
		return '<base href="' . Agis::get('baseHref') . '"/>';
	}

	/**
	 * flatten opengrap to meta, it is helpful for social sites to know what is this
	 * site
	 * @return string
	 */
	public function getHtmlFromOpengraph()
	{
		return '';
	}

	/**
	 * @param string $name
	 * @return bool
	 */
	public function isEmpty($name)
	{
		return !isset($this -> _vars[$name]) || empty($this -> _vars[$name]);
	}

	/**
	 * match action
	 * @param string $name
	 * @param string $option
	 * @param string $default
	 */
	protected function _batchEmpty($name, $option, $default = '')
	{

		$value = $this -> getOption($option, $default = '');

		if (isset($this -> _vars[$name]) && !empty($this -> _vars[$name]))
		{
			$this -> process($this -> getOption($option . '-option', ' append'), $name, $value);
		}
		else
		{
			$this -> process('set', $name, $value);
		}
		return $this;
	}

	public function addMeta($value)
	{
		$this -> _vars['meta'][] = $value;
		return $this;
	}

	/**
	 * @return string
	 */
	public function __toString()
	{
		/**
		 * process some thing else as content or not of page.
		 */
		$this -> addMeta(array(
				'http-equiv' => 'content-type',
				'content' => 'text/html; charset=utf-8'
		)) -> addMeta(array(
				'http-equiv' => 'content-language',
				'content' => $this -> getOption('content-language', 'en-us')
		)) -> addMeta(array(
				'name' => 'owner',
				'content' => $this -> getOption('owner')
		)) -> addMeta(array(
				'name' => 'author',
				'content' => $this -> getOption('author')
		)) -> addMeta(array(
				'name' => 'generator',
				'content' => $this -> getOption('generator')
		)) -> addLink(array(
				'rel' => 'shortcut icon',
				'type' => 'image/x-icon',
				'href' => 'http://namnv.younetco.com/nuo2/favicon.ico'
		)) -> _batchEmpty('Title', 'title', 'untitled name') -> _batchEmpty('Keyword', 'keyword', '') -> _batchEmpty('Description', 'description', '');

		$theme = Agis::get('theme');

		$this
		-> prependCssLink('/nuo2/static/minify/index.php?g=require.css&b=nuo2')
        -> prependCssLink('/nuo2/static/' . $theme . '/styles/main.css') 
        -> prependJsLink('/nuo2/static/minify/index.php?g=require.js&b=nuo2')
        -> prependJsLink('/nuo2/static/minify/index.php?g=main.js&b=nuo2');;

		/**
		 * @var array
		 */
		$allows = array(
				'Base',
				'Link',
				'CssLink',
				'Meta',
				'Opengraph',
				'Keyword',
				'Description',
				'Title',
				'HeadScript',
				'Css',
				'JsLink',
				'Script'
		);

		/**
		 * @var array
		 */
		$xhtml = array();

		foreach ($allows as $allow)
		{
			if (method_exists($this, $method = 'getHtmlFrom' . $allow) && ($html = $this -> {$method}()) != '')
			{
				$xhtml[] = $html;
			}
		}
		return implode(PHP_EOL, $xhtml);
	}

	public function correctCssLink($value)
	{
		if (is_string($value))
		{
			$value = array('href' => $value);
		}
		return array_merge(array(
				'type' => 'text/css',
				'rel' => 'stylesheet',
				'media' => 'all',
				'charset' => 'utf-8'
		), $value);
	}

	public function correctJsLink($value)
	{
		if (is_string($value))
		{
			$value = array('src' => $value);
		}
		return array_merge(array(
				'type' => 'text/javascript',
				'charset' => 'utf-8'
		), $value);
	}

	public function __call($name, $args)
	{
		return $this -> process($name, $name, isset($args[0]) ? $args[0] : null);
	}

	/**
	 * placement
	 * @param string $name
	 * @param string/array $value
	 * @return mixed
	 */
	protected function process($action, $name, $value = null)
	{
		/**
		 * @var string $type
		 */
		$action = substr($action, 0, 3);

		$key = strtolower(preg_replace('#^[a-z]+#', '', $name));

		if (!isset($this -> _vars[$key]))
		{
			$this -> _vars[$key] = array();
		}

		if (method_exists($this, $method = 'correct' . $key))
		{
			$value = $this -> {$method}($value);
		}

		switch($action) {
			case 'app' :
			case 'add' :
				$this -> _vars[$key][] = $value;
				return $this;
			case 'pre' :
				$this -> _vars[$key] = array_reverse($this -> _vars[$key]);
				$this -> _vars[$key][] = $value;
				$this -> _vars[$key] = array_reverse($this -> _vars[$key]);
				return $this;
			case 'cle' :
				$this -> _vars[$key] = array();
				return $this;
			case 'set' :
				$this -> _vars[$key] = array($value);
			case 'has' :
				return isset($this -> _vars[$key]) && !empty($this -> _vars[$key]);
			case 'none' :
		}
		return $this;
	}

	protected function __flattenAttribs($array)
	{
		$xhtml = array();
		foreach ($array as $key => $value)
		{
			$xhtml[] = sprintf('%s="%s"', $key, $value);
		}
		return implode(' ', $xhtml);
	}

}
